/**
 * 基本信息
 *
 * @format
 */

import { BaseDao, TBAPIS } from '../../sdk'
import { JOIN_DB_NAME } from '../../db'
import { ACTIVITY_STATUS } from '../../constants'
import { getToday, getYearWeek } from '../../utils'
import UserService from './user.service'

export default class GameService extends UserService {
  context: IContext<IParams>
  joindao: IBaseDao
  constructor(context: IContext<IParams>) {
    super(context)
    this.joindao = new BaseDao(context, JOIN_DB_NAME)
  }

  async addJoinRecord(userInfo: IUserInfo, vipInfo: IVipInfo) {
    const {
      openId,
      data: { activityId, inviteId }
    } = this.context
    const { userNick, avatar } = userInfo
    const { isVip } = vipInfo
    const now = Date.now()
    const today = getToday()
    const record: IJoinRecord = {
      activityId,
      userNick,
      avatar,
      openId,
      createTime: now,
      updateTime: now,
      score: 0,
      createDay: today,
      createWeek: getYearWeek(),
      inviteId,
      isVip,
      status: 1,
      useTimeToolCount: 0,
      isDraw: false
    }

    const id = await this.joindao.insertOne(record)

    return { id }
  }

  async submitGame(
    id: string,
    score: number,
    rankKey: string,
    rankTime: string,
    userInfo: IUserInfo,
    joinInfo: IJoinRecord
  ) {
    const {
      data: { activityId }
    } = this.context
    const gameResult = await this.joindao.update(
      {
        _id: id,
        $where: `this.status === 1`
      },
      {
        $set: {
          status: 2
        }
      }
    )
    if (gameResult !== 1) {
      // 该局游戏实际已结束，有并发
      return { data: 1 }
    }
    const { duration } = await this.updateJoinRecord(id, score, userInfo, joinInfo)

    const { maxScore, totalScore } = await this.updateUserScore(score, userInfo)

    let totalCount = await this.joindao.count({ activityId, createWeek: joinInfo.createWeek, status: 2 })

    if (totalCount === 1) {
      const arr = []
      for(let i = 0; i < 20; i ++) {
        const now = Date.now()
        arr.push({
          activityId,
          createTime: now,
          updateTime: now,
          score: (i + 1) * 1000,
          createDay: getToday(),
          createWeek: getYearWeek(),
          status: 2,
          useTimeToolCount: 0,
          isDraw: false
        })
      }
      await this.joindao.insertMany(arr)
      totalCount = 21
    }

    const afterCount = await this.joindao.count({ activityId, createWeek: joinInfo.createWeek, status: 2, score: { $lt: score } })

    const { gameTimes, avatar, userNick } = userInfo

    return {
      score,
      maxScore,
      totalScore,
      gameTimes,
      duration,
      avatar,
      userNick,
      rank: ((afterCount / totalCount) * 100).toFixed(0),
      isNew: userInfo.maxScore < score
    }
  }

  async updateJoinRecord(id: string, score: number, userInfo: IUserInfo, joinInfo: IJoinRecord) {
    const now = Date.now()
    const today = getToday()
    const duration = now - joinInfo.createTime
    const playInfo = {
      score,
      duration,
      submitTime: now,
      updateTime: now,
      submitDay: today
    }

    await this.joindao.update({ _id: id }, { $set: playInfo })

    return playInfo
  }

  async updateUserScore(score: number, userInfo: IUserInfo) {
    const now = Date.now()
    const newMaxScore = score >= userInfo?.maxScore
    const maxScore = newMaxScore ? score : userInfo?.maxScore
    const updateScoreTime = newMaxScore ? now : userInfo?.updateScoreTime

    const { _id, totalScore } = userInfo

    // await this.updateUser(_id, {
    //   $set: { maxScore, updateScoreTime },
    //   $inc: { totalScore: score }
    // })

    return {
      maxScore,
      updateScoreTime,
      totalScore: totalScore + score
    }
  }
}
